# 此类只针对单台设备的告警信息
module Aio::Text
  class Warning

    attr_reader :warning_info

    def initialize
      @warning_info = {
        :serious  => {},
        :ordinary => {},
        :compare 	=> Aio::Text::Compare.new,
      }
    end

    def clear
      @warning_info.each_pair { |_, v| v.clear }
    end

    # 判断是否需要添加警告
    # info = iface
    # sym = :errors
    # mod = CMD模块self
    # force 是否直接添加到warning_info中
    # 	如果是否,这相当于update
    def warning(info, sym, level, mod, force=nil)
      benchmark = mod.benchmark[sym]
      var = info[sym]

      # 支持有多个条件的基准值, 只要有一个符合标准就通过
      if force.nil?
        cond_num = benchmark.size - 1
        i = 1
        res = []
        cond_num.times do 
          case benchmark[i]
          when String
            var = var.to_s
          when Integer
            var = var.to_i
          when Float
            var = var.to_f
          end 
          # 还有种情况是正则的方式

          var = var 
          ben = benchmark[i]

          res << case benchmark[0]
          when "=="
            var == ben 
          when "=~"
            var.match(Regexp.new(ben)) ? true : false
          when "!="
            var != ben 
          when ">" 
            var > ben 
          when ">="
            var >= ben 
          when "<" 
            var < ben 
          when "<="
            var <= ben 
          end

          i += 1
        end
        # 当 force 为假的时候,说明不需要加入到warning中,所以 res 为真
      elsif force == false
        res = [true]

        # 当 force 为真的时候,说明需要加入到warning中,所以 res 为假
      elsif force == true
        res = [false]
      end

      unless res.include?(true)
        if filter?(level, sym)
          @warning_info[level][sym] ||= []
          @warning_info[level][sym] << info	
          #pp "#{mod.ext_info[:device_name]} : #{level} : #{sym}"
        end
      end
    end

    def warning_serious(info, sym, mod, force=nil)
      warning(info, sym, :serious, mod, force)
    end

    def warning_ordinary(info, sym, mod, force=nil)
      warning(info, sym, :ordinary, mod, force)
    end

    def warning_compare(info)
      @warning_info[:compare] << info
    end

    def warning_info_serious
      @warning_info[:serious]
    end

    def warning_info_ordinary
      @warning_info[:ordinary]
    end

    def warning_info_compare
      @warning_info[:compare]
    end

    # 判断是否有警告信息
    def has_warning?
      return true unless warning_info_serious.empty?
      return true unless warning_info_ordinary.empty?
      return true unless warning_info_compare.empty?
      return false
    end

    def has_warning_serious?
      warning_info_serious.empty? ? false : true
    end

    def has_warning_ordinary?
      warning_info_ordinary.empty? ? false : true
    end

    def has_warning_compare?
      warning_info_compare.empty? ? false : true
    end

    # 警告数量
    def serious_number
      warning_info_serious.size
    end

    def ordinary_number
      warning_info_ordinary.size
    end

    def compare_number
      warning_info_compare.size
    end

    def total_number
      serious_number + ordinary_number + compare_number
    end

    # 判断是否有指定的警告信息
    # 不对compare 进行判断,因为compare 的格式还没有统一
    def include_warning?(warn)
      warn = warn[0].to_sym if warn.class == ::Array
      return true if include_warning_serious?(warn)
      return true if include_warning_ordinary?(warn)
      #return true if include_warning_compare?(warn)
      return false
    end

    def include_warning_serious?(warn)
      warn = warn[0].to_sym if warn.class == ::Array
      warning_info_serious.has_key?(warn) ? true : false
    end

    def include_warning_ordinary?(warn)
      warn = warn[0].to_sym if warn.class == ::Array
      warning_info_ordinary.has_key?(warn) ? true : false
    end

    # 与Aio::Config::Warning联动，如果里面有sym 的信息，则过滤
    def filter?(level, sym)
      case level
      when :serious
        warn = Aio::Config::Warning::Serious
      when :ordinary
        warn = Aio::Config::Warning::Ordinary
      end
      warn.include?(sym) ? false : true
    end

  end
end

